﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Controllers;
using SageKing.OpenIddict.UI.Api;
using SageKing.OpenIddict.UI.Api.Features;

namespace SageKing.Extensions;

public static class ModuleExtensions
{
    public static IModule OpenIddictUIApiServer(this IModule module, Action<OpenIddictUIApiFeature>? configure = default)
    {
        module.Configure<OpenIddictUIApiFeature>(feature =>
        {
            configure?.Invoke(feature);
        });

        module.UseIceMediatR(o => o.MediatRServiceConfiguration += a =>
        {
            a.RegisterServicesFromAssembly(typeof(OpenIddictUIApiFeature).Assembly);
        });


        return module;
    }
    /// <summary>
    /// Register the Api for the EF based UI Store.
    /// </summary>
    public static OpenIddictBuilder AddUIApis(
      this OpenIddictBuilder builder,
      Action<OpenIddictUIApiOptions> uiApiOptions = null
    )
    {
        var options = new OpenIddictUIApiOptions();
        uiApiOptions?.Invoke(options);
        builder.AddRoutePrefix(options.RoutePrefix);

        builder.Services.AddApiServices(uiApiOptions);

        //builder.Services.AddAuthorizationServices(options.Policy);

        return builder;
    }

    public static IServiceCollection AddApiServices(
      this IServiceCollection services,
      Action<OpenIddictUIApiOptions> options = null
    )
    {
        services.Configure(options);

        services.AddTransient<IScopeApiService, ScopeApiService>();
        services.AddTransient<IApplicationApiService, ApplicationApiService>();
        services.AddTransient<ApplicationApiHttpClient>();

        return services;
    }

    public static IServiceCollection AddAuthorizationServices(
      this IServiceCollection services,
      Action<AuthorizationPolicyBuilder> policy
    )
    {
        services.AddAuthorizationBuilder()
            .AddPolicy(Policies.OpenIddictUiApiPolicy, policy
    );

        return services;
    }

    public static OpenIddictBuilder AddRoutePrefix(
      this OpenIddictBuilder builder,
      string routePrefix
    )
    {
        builder.Services.AddControllers(options =>
        {
            options.UseOpenIddictUIRoutePrefix(
              routePrefix,
              [
                typeof(ApplicationController),
          typeof(ScopeController)
              ]
            );
        });

        return builder;
    }

    public static IServiceCollection AddRoutePrefix(
      this IServiceCollection services,
      string routePrefix
    )
    {
        services.AddControllers(options =>
        {
            options.UseOpenIddictUIRoutePrefix(
              routePrefix,
              [
                typeof(ApplicationController),
          typeof(ScopeController)
              ]
            );
        });

        return services;
    }
}
